home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- #
- # gmailcal: nightly process to generate alternate views of events
- # submitted with gmail(8)
- #
- # usage: gmailcal
- #
- # PASR 01/29/93 Original version (Prentiss Riddle, riddle@rice.edu).
- # PASR 02/03/93 Declared this release 0.2 and sent it out for beta
- # testing.
- # PASR 02/22/93 Declared this release 1.0 for general use.
- # PASR 02/24/93 Portability fix: match year in ctime() results with a
- # pattern rather than a substr() call.
- # PASR 03/07/93 Defined umask in the configuration section.
- # PASR 03/29/93 Fixed bug in calculation of week cuts.
- # Declared this version 1.01.
- #
- # TODO: Make sure all old .cache files get deleted when gmailcal is run.
- # TODO: Think about including a command-line option which causes header
- # info to be read from a file, allowing a single installation to
- # be used in multiple configurations (in particular, to allow
- # multiple events calendars).
- # TODO: Think about putting a chmod in &fixcap.
-
- #--------------------------------------------------------------------------
- # CONFIGURATION: modify these to suit your site!
-
- # Raw calendar data live under here. Note that the alternate views will
- # be *sibling* directories to this one!
- $caldir = "/foo/cwis/gopher/world/Calendars/Events/Upcoming";
-
- # Gopher link information: a Gopher's-eye view of the same directory
- # specified in $caldir.
- $Host = "cwis.foobar.edu";
- $Port = 70;
- $Path = "1/Calendars/Events/Upcoming";
-
- # How many days will we keep old events around in the "../Past" directory?
- $keepold = 183;
-
- # On which day does the week begin? (0=Sunday, 1=Monday)
- $weekbreak = 1;
-
- # How many months ahead will we maintain month-by-month views?
- $monthviews = 5;
-
- # Short description of this events calendar
- # (e.g., "the Foobar University events schedule")
- $description = "the Foobar University events calendar";
-
- # Turn on for noisy output, off for only serious error messages.
- $debug = 0;
-
- # Umask: the Unix file permissions mask. Use 002 if you wish to have
- # files created by gmailcal be group-writeable, 022 otherwise.
- $UMASK = 022;
-
- #--------------------------------------------------------------------------
- # Further initialization (you should probably leave this alone):
-
- require "ctime.pl";
-
- @monthnames =
- ("January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December");
-
- # Recursive "rm" command (very scary!)
- $rm = "/bin/rm -r -f";
-
- umask $UMASK;
-
- # Master "About" file. We will put a link to this in each of the alternate
- # view subdirectories.
- $about = $caldir;
- $about =~ s#(.*)/.*#$1/About#;
- print(STDERR "Warning: \"About\" file $about missing\n") unless (-f $about);
-
- #--------------------------------------------------------------------------
- #
- # Here's the directory structure we're shooting for:
- #
- # Foobar Events/
- # About the Foobar events schedule
- # Search the Foobar events schedule <?>
- # Today/
- # Tomorrow/
- # This week/
- # Next week/
- # January, 1993/
- # February, 1993/
- # March, 1993/
- # ...
- # All upcoming events/
- # Past events/
-
- # We do all of our work relative to $chdir.
- chdir($caldir) || die("Couldn't chdir to $caldir: $!");
-
- # Get various date information relative to today's date.
- $daysec = 24 * 60 * 60;
- $clocktime = time;
- $weekday = substr(&ctime($clocktime), 0, 3);
- $wkdint = index("SunMonTueWedThuFriSat", $weekday) / 3;
- die("Unrecognized weekday: $weekday") if ($wkdint < 0);
-
- $today = &yyyymmdd($clocktime);
- $tomorrow = &yyyymmdd($clocktime + $daysec);
- $pastcut = &yyyymmdd($clocktime - $keepold * $daysec);
- $thisweekcut = &yyyymmdd($clocktime + (6 - $wkdint + $weekbreak) * $daysec);
- $nextweekcut = &yyyymmdd($clocktime + (13 - $wkdint + $weekbreak) * $daysec);
-
- $mm = substr($today, 5, 2);
- $yyyy = substr($today, 0, 4);
- $monthcuts[0] = substr($today, 0, 7);
- for ($i = 1 ; $i < $monthviews ; $i++) {
- #$mm .= ""; # Force into a string context!
- $mm++;
- if ($mm gt "12") {
- $mm = "01";
- $yyyy++;
- }
- $monthcuts[$i] = $yyyy . "-" . $mm;
- }
-
- # Delete old month directories and corresponding .cap files.
- opendir(PARENT, "..") || die("Couldn't open parent directory: $!");
- foreach $dir (grep(/^\d\d\d\d-\d\d$/, readdir(PARENT))) {
- print("Deleting: ../$dir ../cap/$dir\n") if $debug;
- system("$rm ../$dir");
- unlink("../.cap/$dir");
- }
- closedir(PARENT);
-
- # Arrange the directories where the alternate views will go.
- &fixcap("../About", "About " . $description, 1);
- $todaydir = "../Today"; &fixdir($todaydir, "Today", 2);
- $tomorrowdir = "../Tomorrow"; &fixdir($tomorrowdir, "Tomorrow", 3);
- $thisweekdir = "../This_week"; &fixdir($thisweekdir, "This week", 4);
- $nextweekdir = "../Next_week"; &fixdir($nextweekdir, "Next week", 5);
- for ($i = 0 ; $i < $monthviews ; $i++) {
- $monthdirs[$i] = "../" . $monthcuts[$i];
- $monthtitles[$i] = $monthnames[substr($monthcuts[$i], 5, 2) - 1]
- . ", " . substr($monthcuts[$i], 0, 4);
- &fixdir($monthdirs[$i], $monthtitles[$i], $i + 6);
- }
- &fixcap($caldir, "All upcoming events", $monthviews + 6);
- $pastdir = "../Past"; &fixdir($pastdir, "Past events", $monthviews + 7);
-
- # Open .links files and put a link to the "About" file in each one.
- &openlink("UPCOMING", "$caldir/.links"); close(UPCOMING);
- &openlink("PAST", "$pastdir/.links"); close(PAST);
- &openlink("TODAY", "$todaydir/.links");
- &openlink("TOMORROW", "$tomorrowdir/.links");
- &openlink("THISWEEK", "$thisweekdir/.links");
- &openlink("NEXTWEEK", "$nextweekdir/.links");
- $month = 0;
- &openlink("MONTH", "$monthdirs[$month]/.links");
-
- # MAIN LOOP: Step through the calendar events in $caldir, creating links
- # to them as necessary.
- opendir(CALDIR, ".") || die("Couldn't open $caldir: $!");
- MAINLOOP:
- foreach $event sort(grep(/^\d\d\d\d-\d\d-\d\d/, readdir(CALDIR))) {
- print("Processing event: \"$event\"\n") if $debug;
- $matchdate = substr($event, 0, 10);
- if ($matchdate lt $today) {
- # Move this event to $pastdir, including its .cap file.
- print "Moving past event: \"$event\"\n" if $debug;
- rename($event, "$pastdir/$event") ||
- die("Can't move $event to $pastdir: $!");
- rename(".cap/$event", "$pastdir/.cap/$event");
- } else {
- # Does the event match today, tomorrow, this or next week?
- if ($matchdate eq $today) {
- &makelink($event, "TODAY");
- } elsif ($matchdate eq $tomorrow) {
- &makelink($event, "TOMORROW");
- }
- if ($matchdate le $thisweekcut) {
- &makelink($event, "THISWEEK");
- } elsif ($matchdate gt $thisweekcut && $matchdate le $nextweekcut) {
- &makelink($event, "NEXTWEEK");
- }
- # Match "../yyyy-mm" against the current $monthdirs[].
- $matchdate = "../" . substr($event, 0, 7);
- while ($matchdate gt $monthdirs[$month] && $month < $monthviews - 1) {
- # New month.
- $month++;
- close(MONTH);
- &openlink("MONTH", "$monthdirs[$month]/.links");
- }
- if ($matchdate eq $monthdirs[$month]) {
- &makelink($event, "MONTH");
- }
- }
- }
- closedir(CALDIR);
- close(TODAY);
- close(TOMORROW);
- close(THISWEEK);
- close(NEXTWEEK);
- close(MONTH);
-
- # Remove ancient events from the "Past events" directory (including
- # their .cap files).
- opendir(PAST, $pastdir) || die("Couldn't open directory $pastdir: $!");
- PASTLOOP:
- foreach $event (grep(/^\d\d\d\d-\d\d-\d\d/, readdir(PAST))) {
- if ($event lt $pastcut) {
- print("Deleting old event: $pastdir/$event\n") if $debug;
- unlink("$pastdir/$event");
- unlink("$pastdir/.cap/$event");
- }
- }
- closedir(PAST);
-
- #--------------------------------------------------------------------------
- # fixcap -- fill out a ".cap" file, given a filename, title and position
- #
- # usage: &fixcap($filename, $title, $position);
-
- sub fixcap {
- local($filename, $title, $position) = @_;
- local($dirname);
-
- print "fixcap(\"$filename\", \"$title\", $position);\n" if $debug;
- # Insert ".cap/" in the filename.
- $filename =~ s#(.*)/(.*)#$1/.cap/$2#;
- $dirname = $filename;
- $dirname =~ s#(.*/\.cap)/.*#$1#;
- unless (-d $dirname) {
- mkdir($dirname, 0755) ||
- die("Can't create .cap directory $dirname: $!");
- }
- open (CAP, "> $filename") || die("Can't open .cap file $filename: $!");
- print(CAP "Name=$title\nNumb=$position\n");
- close (CAP);
- }
- #--------------------------------------------------------------------------
- # fixdir -- prepare a directory which is to contain an alternate view
- #
- # Side effects:
- # -- creates the named directory, if necessary
- # -- creates a ".cap" subdirectory within the named directory, if necessary
- # -- deletes a ".links" file within the named directory, if necessary
- # -- calls &fixcap to set the title and position of the named directory
- # within its parent directory
- #
- # usage: &fixdir($directory, $title, $position);
-
- sub fixdir {
- local($directory, $title, $position) = @_;
-
- unless (-d $directory) {
- mkdir($directory, 0755) ||
- die("Can't create directory $directory: $!");
- }
- unless (-d "$directory/.cap") {
- mkdir("$directory/.cap", 0755) ||
- die("Can't create directory $directory/.cap: $!");
- }
- unlink("$directory/.links") if (-f "$directory/.links");
- print "fixdir(\"$directory\", \"$title\", $position);\n" if $debug;
- &fixcap($directory, $title, $position);
- }
- #--------------------------------------------------------------------------
- # makelink -- make a link to a given event in a given .links file
- #
- # usage: &makelink($event, $filehandle);
- #
- # global variables used: $caldir $Host $Port $Path $eventpath $debug
-
- sub makelink {
- local($event, $fh) = @_;
- local($name);
-
- print "makelink(\"$event\", \"$fh\");\n" if $debug;
-
- # Read the name from the .cap file corresponding to the event.
- open(CAP, "< $caldir/.cap/$event");
- CAPLOOP:
- while (<CAP>) {
- if (/^Name=/) {
- $name = $_;
- $name =~ s/^Name=//;
- last CAPLOOP;
- }
- }
- close(CAP);
-
- # Complain and exit if we couldn't read it.
- unless ($name) {
- print(STDERR "Error: Couldn't read .cap file for $event\n");
- return;
- }
-
- print($fh "#\n");
- print($fh "Name=$name");
- print($fh "Host=$Host\n");
- print($fh "Type=0\n");
- print($fh "Port=$Port\n");
- unless ($eventpath) {
- $eventpath = $Path;
- $eventpath =~ s/^1/0/;
- }
- print($fh "Path=$eventpath/$event\n");
- }
- #--------------------------------------------------------------------------
- # monthindex -- given a three-character month abbreviation, return the
- # corresponding integer "01" (January) to "12" (December)
- #
- # usage: $mm = &monthindex($monthstr);
- # error: return -1 in case of error;
-
- sub monthindex {
- local($monthstr) = @_;
- local($mm);
- $monthstr =~ tr/A-Z/a-z/;
- $mm = index("janfebmaraprmayjunjulaugsepoctnovdec", $monthstr) / 3 + 1;
- $mm = -1 if ($mm <= 0 || $mm > 12);
- $mm = "0" . $mm if ($mm > 0 && $mm < 10);
- return $mm;
- }
- #--------------------------------------------------------------------------
- # openlink -- open a ".links" file
- #
- # usage: &openlink($filehandle, $filename);
- #
- # Global variables used: $about $description $Host $Port $Path $aboutpath
- #
- # Side effects:
- # -- Opens the .links file specified by $filename
- # -- Writes to it a link to the "About" file
-
- sub openlink {
- local($fh, $filename) = @_;
-
- print "openlink(\"$fh\", \"$filename\");\n" if $debug;
- open($fh, "> $filename") ||
- die("Can't open .links file $filename: $!");
- print($fh "# This file is automatically generated. Don't touch!\n");
- print($fh "#\n");
- # Kluge alert: for some reason "Numb=1" doesn't work here, so
- # we resort to the old initial-space-in-a-Name trick. :-(
- print($fh "Name= About $description\n");
- #print($fh "Numb=1\n");
- print($fh "Type=0\n");
- print($fh "Host=$Host\n");
- print($fh "Port=$Port\n");
- unless ($aboutpath) {
- $aboutpath = $Path;
- $aboutpath =~ s#(.*)/.*#$1/About#;
- $aboutpath =~ s/^1/0/;
- }
- print($fh "Path=$aboutpath\n");
- }
- #--------------------------------------------------------------------------
- # yyyymmdd -- given a clocktime (in seconds since the epoch), return the
- # corresponding date in the format "yyyy-mm-dd"
- #
- # usage: $date = &yyyymmdd($clocktime);
- #
- #
- # Portability issue: we count on &ctime() to return the date in one of
- # the two following formats:
- #
- # Wed Feb 24 10:42:22 1993
- # Wed Feb 24 10:42:22 CST 1993
- #
- # If it doesn't, we're in trouble...
-
- sub yyyymmdd {
- local($clocktime) = @_;
- local($date, $yyyy, $mm, $dd);
- $date = &ctime($clocktime);
- ($yyyy) = $date =~ /\s(\d\d\d\d)\s*$/;
- $mm = &monthindex(substr($date, 4, 3));
- $dd = substr($date, 8, 2);
- $dd =~ s/ /0/;
- return($yyyy . "-" . $mm . "-" . $dd);
- }
- #--------------------------------------------------------------------------
- # end of gmailcal script
-